#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
// 懒汉模式 - 静态成员变量
// 优点：程序启动时不创建对象，节省资源
// 缺点：需要加锁，线程安全
class Singleton
{
private:
    // 私有构造函数，防止外部创建对象
    Singleton()
    {
        std::cout << "Singleton instance created." << std::endl;
    }

    // 禁用拷贝构造函数
    Singleton(const Singleton &) = delete;
    // 禁用赋值运算符
    Singleton &operator=(const Singleton &) = delete;

    // 静态成员变量，存储单例对象的指针
    static Singleton *instance;
    // 静态成员变量，用于 std::call_once 的标志
    static std::once_flag onceFlag;

    // 静态成员函数，用于创建单例对象
    static void createInstance()
    {
        instance = new Singleton();
    }

public:
    // 静态成员函数，获取单例对象的引用
    static Singleton &getInstance()
    {
        // 保证 createInstance 只被调用一次 只能在多线程环境下使用
        std::call_once(onceFlag, createInstance);
        return *instance;
    }

    // 析构函数
    ~Singleton()
    {
        std::cout << "Singleton instance destroyed." << std::endl;
    }
};

// 初始化静态成员变量
Singleton *Singleton::instance = nullptr;
std::once_flag Singleton::onceFlag;
// 线程函数，用于调用 getInstance 方法
void threadFunction()
{
    Singleton &singleton = Singleton::getInstance();
    std::cout << "Thread ID: " << std::this_thread::get_id() << ", Singleton address: " << &singleton << std::endl;
}
int main()
{
    // Singleton &s1 = Singleton::getInstance();
    // Singleton &s2 = Singleton::getInstance();

    // // 验证两个引用指向同一个对象
    // std::cout << "Address of s1: " << &s1 << std::endl;
    // std::cout << "Address of s2: " << &s2 << std::endl;

    const int numThreads = 10;
    std::vector<std::thread> threads;

    // 创建多个线程
    for (int i = 0; i < numThreads; ++i)
    {
        threads.emplace_back(threadFunction);
    }

    // 等待所有线程完成
    for (auto &thread : threads)
    {
        thread.join();
    }
    return 0;
}